home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / jovept1.arc / EXTEND.C < prev    next >
Text File  |  1985-05-30  |  9KB  |  461 lines

  1. /* extend.c */
  2.  
  3. /* JOVE/MSDOS. K. Mitchum 1/85 */
  4. /* Modifications for personal use only. */
  5. /* original code J. Payne LSRHS 5/83 */
  6. /* Ken Mitchum */
  7. /* University of Pittsburgh */
  8. /* Decision Systems Laboratory */
  9.  
  10. /*
  11.    Jonathan Payne at Lincoln-Sudbury Regional High School 4-19-83
  12.   
  13.    jove_extend.c
  14.  
  15.    This contains the TENEX style command completion routine and
  16.    various random routines.  This is not well organized...use the
  17.    tags feature of jove to find your way around...  */
  18.  
  19. #include "jove.h"
  20.  
  21.  
  22. extern int getch(), getchar();
  23. extern int UseBuffers;
  24. extern FUNCT functions[NFUNCS],    /* Wired functions */
  25.         macros[NMACROS],    /* Macros */
  26.         variables[NVARS];    /* Variables */
  27. extern char    quots[];
  28. extern int    EscPrefix(),
  29.         CtlxPrefix();
  30.  
  31. static int InJoverc = 0;
  32.  
  33. min(a, b)
  34. {
  35.     return a < b ? a : b;
  36. }
  37.  
  38. BindAKey()
  39. {
  40.     BindSomething(functions);
  41. }
  42.  
  43. BindMac()
  44. {
  45.     BindSomething(macros);
  46. }
  47.  
  48. BindSomething(funcs)
  49. FUNCT *funcs;
  50. {
  51.     char    *prompt;
  52.     int    c,
  53.         command;
  54.  
  55.     prompt = FuncName();
  56.     command = findcom(funcs, prompt);
  57.     s_mess("%s%s ", prompt, funcs[command].f_name);
  58.     Asking = strlen(mesgbuf);
  59.     if ((c = (*Gtchar)()) == EOF)
  60.         return;
  61.     s_mess("%s%s %c%s", prompt, funcs[command].f_name, c,
  62.                 (c == '\033' || c == CTL(X)) ? "-" : "");
  63.     Asking = strlen(mesgbuf);
  64.     if (c != '\033' && c != CTL(X))
  65.         mainmap[c] = &funcs[command];
  66.     else {
  67.         int    next = (*Gtchar)();
  68.  
  69.         if (next == EOF)
  70.             return;
  71.         ignore(sprintf(&mesgbuf[strlen(mesgbuf)], "%c", next));
  72.         if (c == CTL(X))
  73.             pref2map[next] = &funcs[command];
  74.         else
  75.             pref1map[next] = &funcs[command];
  76.     }
  77.     Asking = 0;
  78. }
  79.  
  80. UnBound()
  81. {
  82.     Beep();
  83. }
  84.  
  85. /* Describe key */
  86.  
  87.  
  88. KeyDesc()
  89. {
  90.     int    key;
  91.     s_mess(FuncName());
  92.     UpdateMesg();
  93.     key = getchar();
  94. #ifdef UNIX
  95.     if (mainmap[key]->f.Func == &EscPrefix)
  96.         DoKeyDesc(pref1map, key);
  97.     else if (mainmap[key]->f.Func == &CtlxPrefix)
  98. #else
  99.     if (mainmap[key]->f.Func ==  eprefix)
  100.         DoKeyDesc(pref1map, key);
  101.     else if ((long) mainmap[key]->f.Func == cprefix)
  102. #endif
  103.         DoKeyDesc(pref2map, key);
  104.     else
  105.         DoKeyDesc(mainmap, key);
  106. }
  107.  
  108. DoKeyDesc(map, key)
  109. FUNCT    **map;
  110. {
  111.     int    c;
  112.  
  113.     if (map != mainmap) {
  114.         s_mess("%s%c-", FuncName(), key);
  115.         UpdateMesg();
  116.         c = getchar();
  117.         s_mess("%s%c-%c", FuncName(), key, c);
  118.     }
  119.     if (map[c] == 0)
  120.         s_mess("%c-%c isn't bound to anything", key, c);
  121.     else
  122.         s_mess("%c-%c is bound to the command %s",
  123.                     key, c, map[c]->f_name);
  124. }
  125.         
  126. DescCom()
  127. {
  128.     int    com;
  129.     FUNCT    *fp;
  130.     WINDOW    *savewp = curwind;
  131.  
  132.     com = findcom(functions, FuncName());
  133.     if (com < 0)
  134.         complain("No such command");
  135.     fp = &functions[com];
  136. #ifdef UNIX
  137.     ignore(UnixToBuf("Command Description", 0, exp_p == 0,
  138.                     FINDCOM,
  139.                     "describe",
  140.                     fp->f_name, 0));
  141.     message("Done");
  142. #else
  143.     message("Desc. not implemented.");
  144. #endif
  145.     SetWind(savewp);
  146. }
  147.  
  148.  
  149. Apropos()
  150. {
  151.     register FUNCT    *fp;
  152.     char    *ans;
  153.  
  154.     ans = ask((char *) 0, "Apropos (keyword) ");
  155.     if (UseBuffers) {
  156.         TellWBuffers("Apropos", 0);
  157.         curwind->w_bufp->b_type = SCRATCHBUF;
  158.     } else
  159.         TellWScreen(0);
  160.     for (fp = functions; fp->f_name; fp++)
  161.         if (sindex(ans, fp->f_name))
  162.             ignore(DoTell(fp->f_name));
  163.  
  164.     for (fp = variables; fp->f_name; fp++)
  165.         if (sindex(ans, fp->f_name))
  166.             ignore(DoTell(fp->f_name));
  167.  
  168.     for (fp = macros; fp->f_name; fp++)
  169.         if (sindex(ans, fp->f_name))
  170.             ignore(DoTell(fp->f_name));
  171.  
  172.     if (UseBuffers) {
  173.         Bof();        /* Go to the beginning of the file */
  174.         NotModified();
  175.     }
  176.     StopTelling();
  177. }
  178.  
  179. sindex(pattern, string)
  180. register char    *pattern,
  181.         *string;
  182. {
  183.     register int    len = strlen(pattern);
  184.  
  185.     while (*string) {
  186.         if (*pattern == *string && strncmp(pattern, string, len) == 0)
  187.             return 1;
  188.         string++;
  189.     }
  190.     return 0;
  191. }
  192.  
  193. Extend()
  194. {
  195.     int    command;
  196.  
  197.     command = findcom(functions, ": ");
  198.     if (command >= 0)
  199.         ExecFunc(&functions[command], !InJoverc);
  200. }
  201.  
  202. AskInt(prompt)
  203. char    *prompt;
  204. {
  205.     char    *val = ask((char *) 0, prompt);
  206.     int    value;
  207.  
  208.     if (strcmp(val, "on") == 0)
  209.         value = 1;
  210.     else if (strcmp(val, "off") == 0)
  211.         value = 0;
  212.     else
  213.         value = atoi(val);
  214.     return value;
  215. }    
  216.  
  217. PrVar()
  218. {
  219.     int    var;
  220.  
  221.     var = findcom(variables, FuncName());
  222.     if (var < 0)
  223.         return;
  224.     s_mess("%s => %d", variables[var].f_name, *(variables[var].f.Var));
  225. }
  226.  
  227. SetVar()
  228. {
  229.     int    command,
  230.         value;
  231.     static char    tmp[70];
  232.  
  233.     strcpy(tmp, ": set ");
  234.     command = findcom(variables, tmp);
  235.     if (command < 0)
  236.         return;
  237.     ignore(sprintf(&tmp[strlen(tmp)], "%s ", variables[command].f_name));
  238.     value = AskInt(tmp);
  239.     *(variables[command].f.Var) = value;
  240.     setfuncs(globflags);
  241. }
  242.             
  243. findcom(possible, prompt)
  244. FUNCT possible[];
  245. char    *prompt;
  246. {
  247.     char    response[132],
  248.         *cp,
  249.         *begin,
  250.         c;
  251.     int    minmatch,
  252.         command,
  253.         i,
  254.         lastmatch,
  255.         numfound,
  256.         length,
  257.         exactmatch;
  258.  
  259.     strcpy(response, prompt);
  260.     message(response);
  261.     Asking = strlen(prompt);
  262.     begin = response + Asking;
  263.     cp = begin;
  264.     *cp = 0;
  265.  
  266.     while (c = (*Gtchar)()) {
  267.         switch (c) {
  268.         case EOF:
  269.             return EOF;
  270.  
  271.         case CTL(U):
  272.             cp = begin;
  273.             *cp = 0;
  274.             break;
  275.  
  276.         case '\r':
  277.         case '\n':
  278.             command = match(possible, begin);
  279.             if (command >= 0) {
  280.                 Asking = 0;
  281.                 return command;
  282.             }
  283.             if (cp == begin) {
  284.                 Asking = 0;
  285.                 return EOF;
  286.             }
  287.             rbell();
  288.             if (InJoverc)
  289.                 return EOF;
  290.             break;
  291.  
  292.         case '\033':        /* Try to complete command */
  293.         case ' ':
  294.             minmatch = 1000;
  295.             numfound = 0;
  296.             exactmatch = lastmatch = -1;
  297.             length = strlen(begin);
  298.             for (i = 0; possible[i].f_name; i++)
  299.                 if (numcomp(possible[i].f_name, begin) >=
  300.                             length) {
  301.                     if (numfound)
  302.                         minmatch = min(minmatch, numcomp(possible[lastmatch].f_name, possible[i].f_name));
  303.                     else
  304.                         minmatch = strlen(possible[i].f_name);
  305.                     lastmatch = i;
  306.                     if (!strcmp(begin, possible[i].f_name))
  307.                         exactmatch = i;
  308.                     numfound++;
  309.                 }
  310.             if (lastmatch >= 0) {
  311.                 strncpy(begin, possible[lastmatch].f_name, minmatch);
  312.                 begin[minmatch] = '\0';
  313.                 cp = &begin[minmatch];
  314.                 if (numfound == 1 || exactmatch != -1) {
  315.                     if (c == '\033') {
  316.                         message(response);
  317.                         UpdateMesg();
  318.                     }
  319.                     Asking = 0;
  320.                     return (numfound == 1) ? lastmatch :
  321.                             exactmatch;
  322.                 } else if (c == '\033')
  323.                     rbell();
  324.             } else {
  325.                 rbell();
  326.                 if (InJoverc)
  327.                     return EOF;
  328.             }
  329.             break;
  330.  
  331.         case '?':
  332.             if (InJoverc)
  333.                 return EOF;
  334.             if (UseBuffers) {
  335.                 TellWBuffers("Help", 1);
  336.                 curwind->w_bufp->b_type = SCRATCHBUF;
  337.             } else
  338.                 TellWScreen(0);
  339.             length = strlen(begin);
  340.             for (i = 0; possible[i].f_name; i++)
  341.                 if (numcomp(possible[i].f_name, begin) >= length) {
  342.                     int    what = DoTell(possible[i].f_name);
  343.  
  344.                     if (what == ABORT)
  345.                         goto abort;
  346.                     if (what == STOP)
  347.                         break;
  348.                 }
  349.  
  350.             if (UseBuffers)
  351.                 Bof();
  352.             StopTelling();
  353.             break;
  354.  
  355.         default:
  356.             if ((int)(cp = RunEdit(c, begin, cp, (char *) 0, Gtchar)) == -1)
  357. abort:
  358.                 if (InJoverc)
  359.                     return EOF;
  360.                 else
  361.                     complain("Aborted");
  362.         }
  363.         Asking = cp - response;        /* Wonderful! */
  364.         message(response);
  365.     }
  366.     /* NOTREACHED */
  367. }
  368.  
  369. numcomp(s1, s2)
  370. register char    *s1, *s2;
  371. {
  372.     register int    i;
  373.  
  374.     for (i = 0; s1[i] || s2[i]; i++)
  375.         if (s1[i] != s2[i])
  376.             break;
  377.     return i;
  378. }
  379.  
  380. match(choices, what)
  381. FUNCT    choices[];
  382. char    *what;
  383. {
  384.     int    len,
  385.         i,
  386.         found = 0,
  387.         save,
  388.         exactmatch = -1;
  389.  
  390.     len = strlen(what);
  391.     for (i = 0; choices[i].f_name; i++)
  392.         if (strncmp(what, choices[i].f_name, len) == 0) {
  393.             if (strcmp(what, choices[i].f_name) == 0)
  394.                 exactmatch = i;
  395.             save = i;
  396.             found++;    /* Found one. */
  397.         }
  398.  
  399.     if (found == 0)
  400.         save = -1;
  401.     else if (found > 1) {
  402.         if (exactmatch != -1)
  403.             save = exactmatch;
  404.         else
  405.             save = -1;
  406.     }
  407.             
  408.     return save;
  409. }
  410.  
  411. Source()
  412. {
  413.     char    *com = ask((char *) 0, FuncName());
  414.  
  415.     if (joverc(com) == -1)
  416.         complain(IOerr("read", com));
  417. }
  418.  
  419. joverc(filename)
  420. char    *filename;
  421. {
  422.     if ((Input = open(filename, 0)) == -1) {
  423.         Input = 0;
  424.         return -1;
  425.     }
  426.  
  427.     InJoverc = 1;
  428.     Gtchar = getchar;
  429.     while (Ungetc(getchar()) != EOF)
  430.         Extend();
  431.     InJoverc = 0;
  432.     Gtchar = getch;
  433.     ignore(close(Input));
  434.     Input = 0;
  435.     Asking = 0;
  436.     message("");
  437.     return 1;
  438. }
  439.  
  440. BufPos()
  441. {
  442.     register LINE    *lp = curbuf->b_zero;
  443.     register int    i = 1;
  444.  
  445.     for (i = 1; lp != 0 && lp != curline; i++, lp = lp->l_next)
  446.         ;
  447.     s_mess("line %d, column %d", i, curchar);
  448. }
  449.  
  450.  
  451.  
  452. SetQchars()
  453. {
  454.     char    *chars = ask((char *) 0, FuncName());
  455.  
  456.     strncpy(quots, chars, 10);    /* Hope that they were reasonable characters */
  457. }
  458.  
  459. /*-------------------------o.s. dependent--------------------------*/
  460. /* end */
  461.